Here, we explore bottom temperature and fishing as potential drivers
of spatial beta diversity across trawl regions.
library(data.table)
library(ggplot2)
library(lme4)
library(lmerTest)
library(MuMIn)
###Pull in datatable with dissimilarities, reg characteristics,
fishing, and temperature
#from local (will have to change)
dissimilarities_temp_fishing_regstats <- readRDS(here::here("output","distance_decay","dissimilarities_temp_fishing_regstats.rds"))
###Palette for Plotting Palette for plotting all 37 survey units
(Prep for eventual plots)
survey_unit.list <- levels(dissimilarities_temp_fishing_regstats[,factor(survey_unit)])
palette_37 <- c(
"#5A5156", #AI
"#F6222E", #CHL
"#F8A19F", #DFO-NF
"#16FF32", #DFO-QCS
"#DF00DB", #BITS-1
"#DB8EDA", #BITS-4
"#325A9B", #EBS
"#3283FE", #EVHOE
"#FEAF16", #FR-CGFS
"#1C8356", #GMEX-Summer
"#C4451C", #GOA
"#85660D", #GRL-DE
"#B0009F", #GSL-N
"#BF79B8", #GSL-S
"#1CBE4F", #ICE-GFS
"#782AB6", #IE-IGFS
"#90AD1C", #MEDITS
"#6B003A", #NAM
"#A75B00", #NEUS-Fall
"#E3B072", #NEUS-Spring
"#02E8B6", #NIGFS-1
"#97E7D5", #NIGFS-4
"#B00068", #Nor-BTS-3
"#00B9E3", #NS-IBTS-1
"#95E2F4", #NS-IBTS-3
"#B3CE73", #NZ-CHAT
"#689500", #NZ-ECSI
"#AAF400", #NZ-WCSI
"#AA0DFE", #PT-IBTS
"#FA0087", #S-GEORG
"#DEA0FD", #SCS-Summer
"#FCEF88", #SEUS-fall
"#A59405", #SEUS-spring
"#FCE100", #SEUS-summer
"#C075A6", #WCANN
"#BDCDFF", #ZAF-ATL
"#003EFF" #ZAF-IND
)
color_link <- data.table(survey_unit = survey_unit.list,hex = palette_37)
Add names for plotting
name_helper <- data.table(Survey_Name_Season = c("Aleutian Islands",
"Baltic Sea Q1",
"Baltic Sea Q4",
"Chile",
"Newfoundland",
"Queen Charlotte Sound",
"Eastern Bering Sea",
"Bay of Biscay",
"English Channel",
"Gulf of Mexico",
"Gulf of Alaska",
"Greenland",
"N Gulf of St. Lawrence",
"S Gulf of St. Lawrence",
"Iceland",
"Irish Sea",
"Mediterranean",
"Namibia",
"NE US Fall",
"NE US Spring",
"N Ireland Q1",
"N Ireland Q4",
"Norway",
"N Sea Q1",
"N Sea Q3",
"Chatham Rise",
"E Coast S Island NZ",
"W Coast S Island NZ",
"Portugal",
"S Georgia Straight",
"Scotian Shelf",
"SE US Fall",
"SE US Spring",
"SE US Summer",
"W Coast US",
"Atlantic Ocean ZA",
"Indian Ocean ZA"),
survey_unit = c(
"AI",
"BITS-1",
"BITS-4",
"CHL",
"DFO-NF",
"DFO-QCS",
"EBS",
"EVHOE",
"FR-CGFS",
"GMEX-Summer",
"GOA",
"GRL-DE",
"GSL-N",
"GSL-S",
"ICE-GFS",
"IE-IGFS",
"MEDITS",
"NAM",
"NEUS-Fall",
"NEUS-Spring",
"NIGFS-1",
"NIGFS-4",
"Nor-BTS-3",
"NS-IBTS-1",
"NS-IBTS-3",
"NZ-CHAT",
"NZ-ECSI",
"NZ-WCSI",
"PT-IBTS",
"S-GEORG",
"SCS-SUMMER",
"SEUS-fall",
"SEUS-spring",
"SEUS-summer",
"WCANN",
"ZAF-ATL",
"ZAF-IND"
))
color_link <- color_link[name_helper, on = "survey_unit"]
###First, we built mixed models with raw temperature predictors as
fixed effects and survey as random slope and intercept - Mean bottom
temp 12 months before survey - Max bottom temp 12 years before survey -
Min bottom temp 12 years before survey - Bottom temp seasonality 12
months before survey - Heterogeneity (SD) of mean bottom temp 12 months
before survey - Heterogeneity (SD) of max bottom temp 12 months before
survey - Heterogeneity (SD) of min bottom temp 12 months before survey -
Heterogeneity (SD) of bottom temp seasonalty 12 months before survey
#from local (will have to change)
balanced_dissimilarity_sbt_model_results <- readRDS(here::here("output","balanced_dissimilarity_sbt_model_results.rds"))
setorder(balanced_dissimilarity_sbt_model_results,-AICc)
balanced_dissimilarity_sbt_model_results[Scaled == F,]
The standard deviation of mean temperature and the overall mean
temperature perform equally well. However, neither explain very much
variation at all (R^ of 0.7 and 0.2)
The SD of mean tempereature performs best, but explains little
variation. *Note that this plot is just to help visualize data and
patterns, it does not plot predicted values from the LME but rather just
simple linear models of dissimilarity ~ temp.
ggplot(data = dissimilarities_temp_fishing_regstats) +
labs(x = "SD of mean bottom temperature", y = "Bray Curtis balanced dissimilarity") +
geom_point(aes(x = yearly_mean_bypoint_SD, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
geom_line(aes(x = yearly_mean_bypoint_SD, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), stat="smooth", method = "lm") +
scale_color_manual(values = c(palette_37)) +
geom_smooth(aes(x = yearly_mean_bypoint_SD, y = bray_curtis_dissimilarity_balanced_mean), method = "lm", se = F, color = "black") +
theme_classic()

#facet helpful for visualization
ggplot(data = dissimilarities_temp_fishing_regstats) +
labs(x = "SD of mean bottom temperature", y = "Bray Curtis balanced dissimilarity") +
geom_point(aes(x = yearly_mean_bypoint_SD, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
geom_line(aes(x = yearly_mean_bypoint_SD, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), stat="smooth", method = "lm") +
scale_color_manual(values = c(palette_37)) +
geom_smooth(aes(x = yearly_mean_bypoint_SD, y = bray_curtis_dissimilarity_balanced_mean), method = "lm", se = F, color = "black") +
facet_wrap(~survey_unit, scales = "free") +
theme_classic() + theme(legend.position = "null")

The mean temperature performs equally well, but explains little
variation. *Note that this plot is just to help visualize data and
patterns, it does not plot predicted values from the LME but rather just
simple linear models of dissimilarity ~ temp.
ggplot(data = dissimilarities_temp_fishing_regstats) +
labs(x = "Mean bottom temperature (ËšC)", y = "Bray Curtis balanced dissimilarity") +
geom_point(aes(x = yearly_mean_bypoint_avg, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
geom_line(aes(x = yearly_mean_bypoint_avg, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), stat="smooth", method = "lm") +
scale_color_manual(values = c(palette_37)) +
geom_smooth(aes(x = yearly_mean_bypoint_avg, y = bray_curtis_dissimilarity_balanced_mean), method = "lm", se = F, color = "black") +
theme_classic()

#faceted helpful for visualization
ggplot(data = dissimilarities_temp_fishing_regstats) +
labs(x = "Mean bottom temperature (ËšC)", y = "Bray Curtis balanced dissimilarity") +
geom_point(aes(x = yearly_mean_bypoint_avg, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
scale_color_manual(values = c(palette_37)) +
facet_wrap(~survey_unit, scales = "free") +
geom_smooth(aes(x = yearly_mean_bypoint_avg, y = bray_curtis_dissimilarity_balanced_mean), method = "lm", se = F, color = "black") +
theme_classic() +
theme(legend.position = "null")

###Then, we looked at relative temperature predictors (scaled within
a survey region, so, is this year warm or cool for this region) -
Relative mean bottom temp 12 months before survey - Relative max bottom
temp 12 years before survey - Relative min bottom temp 12 years before
survey - Relative bottom temp seasonality 12 months before survey -
Relative heterogeneity (SD) of mean bottom temp 12 months before survey
- Relative heterogeneity (SD) of max bottom temp 12 months before survey
- Relative heterogeneity (SD) of min bottom temp 12 months before survey
- Relative heterogeneity (SD) of bottom temp seasonalty 12 months before
survey
balanced_dissimilarity_sbt_model_results[Scaled == T,]
The relative mean tempereature performs best, but explains 0
variation. *Note that this plot is just to help visualize data and
patterns, it does not plot predicted values from the LME but rather just
simple linear models of dissimilarity ~ temp.
ggplot(data = dissimilarities_temp_fishing_regstats) +
labs(x = "Mean bottom temperature scaled", y = "Bray Curtis balanced dissimilarity") +
geom_point(aes(x = yearly_mean_bypoint_avg.s, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
geom_line(aes(x = yearly_mean_bypoint_avg.s, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), stat="smooth", method = "lm") +
scale_color_manual(values = c(palette_37)) +
geom_smooth(aes(x = yearly_mean_bypoint_avg.s, y = bray_curtis_dissimilarity_balanced_mean), method = "lm", se = F, color = "black") +
theme_classic()

#faceted helpful for visualization
ggplot(data = dissimilarities_temp_fishing_regstats) +
labs(x = "Mean bottom temperature scaled", y = "Bray Curtis balanced dissimilarity") +
geom_point(aes(x = yearly_mean_bypoint_avg.s, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
geom_line(aes(x = yearly_mean_bypoint_avg.s, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), stat="smooth", method = "lm") +
scale_color_manual(values = c(palette_37)) +
geom_smooth(aes(x = yearly_mean_bypoint_avg.s, y = bray_curtis_dissimilarity_balanced_mean), method = "lm", se = F, color = "black") +
facet_wrap(~survey_unit, scales = "free") +
theme_classic() + theme(legend.position = "null")

###Fishing Pressure Alone
#model ranking for fishing only models
#from local (will have to change)
balanced_dissimilarity_fishing_model_results <-readRDS(here::here("output","balanced_dissimilarity_fishing_model_results.Rds"))
setorder(balanced_dissimilarity_fishing_model_results, -AICc)
balanced_dissimilarity_fishing_model_results
Best model only includes survey unit (probably because of differences
in baseline dissimilarity across regions)
###Now we’ll look at both fishing and bottom temperature as potential
predictors
#model rankings (temp and fishing)
#from local (will have to change)
balanced_dissimilarity_sbt_fishing_model_results <- readRDS(here::here("output", "balanced_dissimilarity_sbt_fishing_model_results.Rds"))
setorder(balanced_dissimilarity_sbt_fishing_model_results, -AICc)
balanced_dissimilarity_sbt_fishing_model_results
Any model with survey as a fixed effect performs better than models
without survey as a fixed effect. Also, there is an interaction between
fishing and survey in 4 of the top 5 performing models.
Significant positive interaction (higher dissimilarity at higher
fishing) - Newfoundland
Significant negative interaction (higher dissimilarity at lower
fishing) - Eastern Bering Sea - France - Gulf of Alaska - Gulf of
St. Lawrence S - Northeast US Fall - Ireland 4th quarter - North Sea
(1st and 3rd quarter) - West Coast and East Coast of South Island of New
Zealand - South Georgia - Scotian Shelf Summer Survey
Plot just dissimilarity ~ relative fishing pressure coefficients of
each region (Like figure 1b) *Note, may be better to include survey as a
fixed effect, but below we include as random slope and intercept
instead.
#lmer with fishing as fixed and survey as random slope and intercept
#fishing and random slope and intercept for survey
allreg_dissimilarity_fishing_mean_mod <- lmer(bray_curtis_dissimilarity_balanced_mean ~ summed_tonnes_scaled_byreg + (1 + summed_tonnes_scaled_byreg|survey_unit), data = dissimilarities_temp_fishing_regstats)
# see group coefficients and confidence intervals
fishing_model_coefs_reduced <- data.table(transform(as.data.frame(ranef(allreg_dissimilarity_fishing_mean_mod)), lwr = condval - 1.96*condsd, upr = condval + 1.96*condsd))
#https://stackoverflow.com/questions/69805532/extract-the-confidence-intervals-of-lmer-random-effects-plotted-with-dotplotra
#ONLY SLOPES
fishing_model_coefs_reduced <- fishing_model_coefs_reduced[term == "summed_tonnes_scaled_byreg",]
fishing_model_coefs_reduced[,survey_unit := grp][,summed_tonnes_scaled_byreg := condval]
fishing_model_coefs_reduced[,Slope_Direction := ifelse(summed_tonnes_scaled_byreg > 0, "Positive","Negative")]
#
fishing_model_coefs_reduced <- fishing_model_coefs_reduced[color_link, on = "survey_unit"]
#does it cross zero?
fishing_model_coefs_reduced[,significant := ifelse(lwr >0 & upr>0,T,ifelse(lwr<0 & upr<0,T,F))]
#delete all obs that are significant
fishing_model_coefs_reduced.r <- fishing_model_coefs_reduced[significant == F,]
#order table by coefficient
setorder(fishing_model_coefs_reduced, summed_tonnes_scaled_byreg)
BC_balanced_fishing_model_coefs_reduced.unique <- unique(fishing_model_coefs_reduced[,.(condval,condsd, lwr, upr, survey_unit, summed_tonnes_scaled_byreg, Slope_Direction, hex, Survey_Name_Season, significant)])
#extract color hexes
#year adj coef order
color_year_adj_order <-BC_balanced_fishing_model_coefs_reduced.unique[,hex]
#alphabetical order
BC_balanced_fishing_model_coefs_reduced.unique.alpha <- setorder(BC_balanced_fishing_model_coefs_reduced.unique, Survey_Name_Season)
color_alpha_order <- BC_balanced_fishing_model_coefs_reduced.unique.alpha[,hex]
ggplot() +
geom_errorbar(data = fishing_model_coefs_reduced, aes(x = reorder(Survey_Name_Season, summed_tonnes_scaled_byreg) , y = summed_tonnes_scaled_byreg, label = Survey_Name_Season, ymin = lwr, ymax = upr), fill = "grey", width = 0) + #add confidence intervals
geom_point(data = fishing_model_coefs_reduced, aes(x = reorder(Survey_Name_Season, summed_tonnes_scaled_byreg) , y = summed_tonnes_scaled_byreg, label = Survey_Name_Season,
fill = Slope_Direction), stat = 'identity', shape = 21, color = "black") +
scale_fill_manual(values = c("white","black"), name = "Slope Direction") +
geom_point(data = fishing_model_coefs_reduced.r, aes(x = reorder(Survey_Name_Season, summed_tonnes_scaled_byreg) , y = summed_tonnes_scaled_byreg,
label = Survey_Name_Season), stat = 'identity', fill = "grey",color = "grey", shape = 21) +
geom_hline(yintercept = 0) +
xlab("Survey unit") +
ylab("Balanced BC dissimilarity ~\nrelative fishing pressure") +
coord_flip() +
theme_classic()
Warning: Ignoring unknown parameters: `fill`Warning: Ignoring unknown aesthetics: labelWarning: Ignoring unknown aesthetics: labelWarning: Ignoring unknown aesthetics: label

#scatterplot
dissimilarities_temp_fishing_regstats.na <- na.omit(dissimilarities_temp_fishing_regstats, cols = "summed_tonnes_scaled_byreg") #delete any rows with NAs
#Predicted values
dissimilarities_temp_fishing_regstats.na$pred_summed_tonnes_scaled_byreg <- predict(allreg_dissimilarity_fishing_mean_mod,re.form=NA) ## population level
dissimilarities_temp_fishing_regstats.na$pred_summed_tonnes_scaled_byreg_individual <- predict(allreg_dissimilarity_fishing_mean_mod) ## individual level
#confidence intervals
fishing_confit <- confint(allreg_dissimilarity_fishing_mean_mod, oldNames = F)
Computing profile confidence intervals ...
#upper lower bounds from confidence intervals
dissimilarities_temp_fishing_regstats.na[,pred_summed_tonnes_scaled_byreg_lwr := fishing_confit[5,1] + fishing_confit[6,1]*summed_tonnes_scaled_byreg]#lower confidence interval
dissimilarities_temp_fishing_regstats.na[,pred_summed_tonnes_scaled_byreg_upr := fishing_confit[5,2] + fishing_confit[6,2]*summed_tonnes_scaled_byreg]#upper confidence interval
#for all regions
ggplot(data = dissimilarities_temp_fishing_regstats.na) +
labs(x = "Relative fishing pressure", y = "BC balanced dissimilarity") +
geom_point(aes(x = summed_tonnes_scaled_byreg, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
geom_line(aes(x = summed_tonnes_scaled_byreg, y = pred_summed_tonnes_scaled_byreg_individual, color = survey_unit)) +
geom_line(aes(x = summed_tonnes_scaled_byreg, y = pred_summed_tonnes_scaled_byreg), lwd = 1) +
scale_color_manual(values = palette_37) +
theme_classic()

#for all regions faceted
ggplot(data = dissimilarities_temp_fishing_regstats.na) +
labs(x = "Relative fishing pressure", y = "BC balanced dissimilarity") +
geom_point(aes(x = summed_tonnes_scaled_byreg, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
geom_line(aes(x = summed_tonnes_scaled_byreg, y = pred_summed_tonnes_scaled_byreg_individual, color = survey_unit)) +
scale_color_manual(values = palette_37) +
facet_wrap(~survey_unit, scales = "free") +
theme_classic() +
theme(legend.position = "null")

NA
NA
NA
Other variables to consider
- Species number (spp_count_annual, different value each region and
year)
Species number in a year vs. dissimilarity
ggplot(data = dissimilarities_temp_fishing_regstats) +
labs(x = "Spp number", y = "BC balanced dissimilarity") +
geom_point(aes(x = spp_count_annual, y = bray_curtis_dissimilarity_balanced_mean, color = survey_unit), alpha = 0.3) +
scale_color_manual(values = palette_37) +
# facet_wrap(~survey_unit, scales = "free") +
theme_classic() +
theme(legend.position = "null")

Species number in a year vs. dissimilarity ~ year coefficient
dissimilarities_temp_fishing_regstats.unique <- unique(dissimilarities_temp_fishing_regstats[,.(year, spp_count_annual, bray_coef, survey_unit)])
ggplot(data = dissimilarities_temp_fishing_regstats.unique) +
labs(x = "Spp number", y = "Bray Curtis dissimilarity ~ year coefficient") +
geom_point(aes(x = spp_count_annual, y = bray_coef, color = survey_unit), alpha = 0.3) +
scale_color_manual(values = palette_37) +
geom_hline(yintercept = 0) +
theme_classic()

Regions that are differentiating (positive slope) tend to have fewer
#s of species. The few regions with a lot of species (over 150; Gulf of
Mexico, West Coast US, Northeast US, Gulf of Alaska), all have negative
coefficients (homogenizing). This is the opposite of what I would have
expected, as more species across a survey region would intuitively allow
for more opportunities to differentiate.
LS0tCnRpdGxlOiAiRHJpdmVycyBvZiBEaXNzaW1pbGFyaXR5IFdhbGsgVGhyb3VnaCAoQm90dG9tIHRlbXAsIGJhbGFuY2VkIEJyYXkgQ3VydGlzIERpc3NpbWlsYXJpdHkpIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpIZXJlLCB3ZSBleHBsb3JlIGJvdHRvbSB0ZW1wZXJhdHVyZSBhbmQgZmlzaGluZyBhcyBwb3RlbnRpYWwgZHJpdmVycyBvZiBzcGF0aWFsIGJldGEgZGl2ZXJzaXR5IGFjcm9zcyB0cmF3bCByZWdpb25zLgoKYGBge3Igc2V0dXB9CmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGxtZTQpCmxpYnJhcnkobG1lclRlc3QpCmxpYnJhcnkoTXVNSW4pCmBgYAoKIyMjUHVsbCBpbiBkYXRhdGFibGUgd2l0aCBkaXNzaW1pbGFyaXRpZXMsIHJlZyBjaGFyYWN0ZXJpc3RpY3MsIGZpc2hpbmcsIGFuZCB0ZW1wZXJhdHVyZQpgYGB7cn0KCiNmcm9tIGxvY2FsICh3aWxsIGhhdmUgdG8gY2hhbmdlKQpkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzIDwtIHJlYWRSRFMoaGVyZTo6aGVyZSgib3V0cHV0IiwiZGlzdGFuY2VfZGVjYXkiLCJkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzLnJkcyIpKQoKYGBgCgojIyNQYWxldHRlIGZvciBQbG90dGluZwpQYWxldHRlIGZvciBwbG90dGluZyBhbGwgMzcgc3VydmV5IHVuaXRzCihQcmVwIGZvciBldmVudHVhbCBwbG90cykKYGBge3IgbGluayBjb2xvcnMgdG8gc3VydmV5IHVuaXRzfQpzdXJ2ZXlfdW5pdC5saXN0IDwtIGxldmVscyhkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzWyxmYWN0b3Ioc3VydmV5X3VuaXQpXSkKCnBhbGV0dGVfMzcgPC0gYygKICAiIzVBNTE1NiIsICNBSQogICIjRjYyMjJFIiwgI0NITAogICIjRjhBMTlGIiwgI0RGTy1ORgogICIjMTZGRjMyIiwgI0RGTy1RQ1MKICAiI0RGMDBEQiIsICNCSVRTLTEKICAiI0RCOEVEQSIsICNCSVRTLTQKICAiIzMyNUE5QiIsICNFQlMKICAiIzMyODNGRSIsICNFVkhPRQogICIjRkVBRjE2IiwgI0ZSLUNHRlMKICAiIzFDODM1NiIsICNHTUVYLVN1bW1lcgogICIjQzQ0NTFDIiwgI0dPQQogICIjODU2NjBEIiwgI0dSTC1ERQogICIjQjAwMDlGIiwgI0dTTC1OCiAgIiNCRjc5QjgiLCAjR1NMLVMKICAiIzFDQkU0RiIsICNJQ0UtR0ZTCiAgIiM3ODJBQjYiLCAjSUUtSUdGUwogICIjOTBBRDFDIiwgI01FRElUUwogICIjNkIwMDNBIiwgI05BTQogICIjQTc1QjAwIiwgI05FVVMtRmFsbAogICIjRTNCMDcyIiwgI05FVVMtU3ByaW5nCiAgIiMwMkU4QjYiLCAjTklHRlMtMQogICIjOTdFN0Q1IiwgI05JR0ZTLTQKICAiI0IwMDA2OCIsICNOb3ItQlRTLTMKICAiIzAwQjlFMyIsICNOUy1JQlRTLTEKICAiIzk1RTJGNCIsICNOUy1JQlRTLTMKICAiI0IzQ0U3MyIsICNOWi1DSEFUCiAgIiM2ODk1MDAiLCAjTlotRUNTSQogICIjQUFGNDAwIiwgI05aLVdDU0kKICAiI0FBMERGRSIsICNQVC1JQlRTCiAgIiNGQTAwODciLCAjUy1HRU9SRwogICIjREVBMEZEIiwgI1NDUy1TdW1tZXIKICAiI0ZDRUY4OCIsICNTRVVTLWZhbGwKICAiI0E1OTQwNSIsICNTRVVTLXNwcmluZwogICIjRkNFMTAwIiwgI1NFVVMtc3VtbWVyCiAgIiNDMDc1QTYiLCAjV0NBTk4KICAiI0JEQ0RGRiIsICNaQUYtQVRMCiAgIiMwMDNFRkYiICAjWkFGLUlORAopCgpjb2xvcl9saW5rIDwtIGRhdGEudGFibGUoc3VydmV5X3VuaXQgPSBzdXJ2ZXlfdW5pdC5saXN0LGhleCA9IHBhbGV0dGVfMzcpCmBgYAoKQWRkIG5hbWVzIGZvciBwbG90dGluZwpgYGB7ciBhZGQgbmFtZXMgZm9yIHBsb3R0aW5nfQoKbmFtZV9oZWxwZXIgPC0gZGF0YS50YWJsZShTdXJ2ZXlfTmFtZV9TZWFzb24gPSBjKCJBbGV1dGlhbiBJc2xhbmRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJhbHRpYyBTZWEgUTEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQmFsdGljIFNlYSBRNCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDaGlsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOZXdmb3VuZGxhbmQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUXVlZW4gQ2hhcmxvdHRlIFNvdW5kIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVhc3Rlcm4gQmVyaW5nIFNlYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJCYXkgb2YgQmlzY2F5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVuZ2xpc2ggQ2hhbm5lbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHdWxmIG9mIE1leGljbyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHdWxmIG9mIEFsYXNrYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHcmVlbmxhbmQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTiBHdWxmIG9mIFN0LiBMYXdyZW5jZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTIEd1bGYgb2YgU3QuIExhd3JlbmNlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkljZWxhbmQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSXJpc2ggU2VhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1lZGl0ZXJyYW5lYW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTmFtaWJpYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORSBVUyBGYWxsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5FIFVTIFNwcmluZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOIElyZWxhbmQgUTEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTiBJcmVsYW5kIFE0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vcndheSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOIFNlYSBRMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOIFNlYSBRMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDaGF0aGFtIFJpc2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRSBDb2FzdCBTIElzbGFuZCBOWiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJXIENvYXN0IFMgSXNsYW5kIE5aIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvcnR1Z2FsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlMgR2VvcmdpYSBTdHJhaWdodCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2NvdGlhbiBTaGVsZiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0UgVVMgRmFsbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0UgVVMgU3ByaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTRSBVUyBTdW1tZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlcgQ29hc3QgVVMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkF0bGFudGljIE9jZWFuIFpBIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbmRpYW4gT2NlYW4gWkEiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdCA9IGMoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQUkiLCAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQklUUy0xIiwgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQklUUy00IiwgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0hMIiwgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiREZPLU5GIiwgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiREZPLVFDUyIsICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRUJTIiwgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRVZIT0UiLCAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRlItQ0dGUyIsICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR01FWC1TdW1tZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdPQSIsICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdSTC1ERSIsICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdTTC1OIiwgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdTTC1TIiwgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIklDRS1HRlMiLCAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIklFLUlHRlMiLCAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1FRElUUyIsICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5BTSIsICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5FVVMtRmFsbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5FVVMtU3ByaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOSUdGUy0xIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOSUdGUy00IiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOb3ItQlRTLTMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOUy1JQlRTLTEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOUy1JQlRTLTMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOWi1DSEFUIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOWi1FQ1NJIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOWi1XQ1NJIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQVC1JQlRTIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTLUdFT1JHIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTQ1MtU1VNTUVSIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTRVVTLWZhbGwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTRVVTLXNwcmluZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0VVUy1zdW1tZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIldDQU5OIiwgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlpBRi1BVEwiLCAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlpBRi1JTkQiICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgKSkKCmNvbG9yX2xpbmsgPC0gY29sb3JfbGlua1tuYW1lX2hlbHBlciwgb24gPSAic3VydmV5X3VuaXQiXQoKYGBgCgoKIyMjRmlyc3QsIHdlIGJ1aWx0IG1peGVkIG1vZGVscyB3aXRoIHJhdyB0ZW1wZXJhdHVyZSBwcmVkaWN0b3JzIGFzIGZpeGVkIGVmZmVjdHMgYW5kIHN1cnZleSBhcyByYW5kb20gc2xvcGUgYW5kIGludGVyY2VwdAotIE1lYW4gYm90dG9tIHRlbXAgMTIgbW9udGhzIGJlZm9yZSBzdXJ2ZXkKLSBNYXggYm90dG9tIHRlbXAgMTIgeWVhcnMgYmVmb3JlIHN1cnZleQotIE1pbiBib3R0b20gdGVtcCAxMiB5ZWFycyBiZWZvcmUgc3VydmV5Ci0gQm90dG9tIHRlbXAgc2Vhc29uYWxpdHkgMTIgbW9udGhzIGJlZm9yZSBzdXJ2ZXkKLSBIZXRlcm9nZW5laXR5IChTRCkgb2YgbWVhbiBib3R0b20gdGVtcCAxMiBtb250aHMgYmVmb3JlIHN1cnZleQotIEhldGVyb2dlbmVpdHkgKFNEKSBvZiBtYXggYm90dG9tIHRlbXAgMTIgbW9udGhzIGJlZm9yZSBzdXJ2ZXkKLSBIZXRlcm9nZW5laXR5IChTRCkgb2YgbWluIGJvdHRvbSB0ZW1wIDEyIG1vbnRocyBiZWZvcmUgc3VydmV5Ci0gSGV0ZXJvZ2VuZWl0eSAoU0QpIG9mIGJvdHRvbSB0ZW1wIHNlYXNvbmFsdHkgMTIgbW9udGhzIGJlZm9yZSBzdXJ2ZXkKCgpgYGB7ciByYXcgdGVtcCBtb2RlbCByZXN1bHRzfQojZnJvbSBsb2NhbCAod2lsbCBoYXZlIHRvIGNoYW5nZSkKYmFsYW5jZWRfZGlzc2ltaWxhcml0eV9zYnRfbW9kZWxfcmVzdWx0cyA8LSByZWFkUkRTKGhlcmU6OmhlcmUoIm91dHB1dCIsImJhbGFuY2VkX2Rpc3NpbWlsYXJpdHlfc2J0X21vZGVsX3Jlc3VsdHMucmRzIikpCgpzZXRvcmRlcihiYWxhbmNlZF9kaXNzaW1pbGFyaXR5X3NidF9tb2RlbF9yZXN1bHRzLC1BSUNjKQoKYmFsYW5jZWRfZGlzc2ltaWxhcml0eV9zYnRfbW9kZWxfcmVzdWx0c1tTY2FsZWQgPT0gRixdCmBgYApUaGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIG1lYW4gdGVtcGVyYXR1cmUgYW5kIHRoZSBvdmVyYWxsIG1lYW4gdGVtcGVyYXR1cmUgcGVyZm9ybSBlcXVhbGx5IHdlbGwuIEhvd2V2ZXIsIG5laXRoZXIgZXhwbGFpbiB2ZXJ5IG11Y2ggdmFyaWF0aW9uIGF0IGFsbCAoUl4gb2YgMC43IGFuZCAwLjIpCgpUaGUgU0Qgb2YgbWVhbiB0ZW1wZXJlYXR1cmUgcGVyZm9ybXMgYmVzdCwgYnV0IGV4cGxhaW5zIGxpdHRsZSB2YXJpYXRpb24uIAoqTm90ZSB0aGF0IHRoaXMgcGxvdCBpcyBqdXN0IHRvIGhlbHAgdmlzdWFsaXplIGRhdGEgYW5kIHBhdHRlcm5zLCAgaXQgZG9lcyBub3QgcGxvdCBwcmVkaWN0ZWQgdmFsdWVzIGZyb20gdGhlIExNRSBidXQgcmF0aGVyIGp1c3Qgc2ltcGxlIGxpbmVhciBtb2RlbHMgb2YgZGlzc2ltaWxhcml0eSB+IHRlbXAuCmBgYHtyIHBsb3QgZGlzc2ltaWxhcml0eSB2cy4gU0Qgb2YgbWVhbiB0ZW1wZXJhdHVyZX0KZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzKSArCiAgbGFicyh4ID0gIlNEIG9mIG1lYW4gYm90dG9tIHRlbXBlcmF0dXJlIiwgIHkgPSAiQnJheSBDdXJ0aXMgYmFsYW5jZWQgZGlzc2ltaWxhcml0eSIpICsKICBnZW9tX3BvaW50KGFlcyh4ID0geWVhcmx5X21lYW5fYnlwb2ludF9TRCwgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiwgY29sb3IgPSBzdXJ2ZXlfdW5pdCksIGFscGhhID0gMC4zKSArCiAgZ2VvbV9saW5lKGFlcyh4ID0geWVhcmx5X21lYW5fYnlwb2ludF9TRCwgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiwgY29sb3IgPSBzdXJ2ZXlfdW5pdCksIHN0YXQ9InNtb290aCIsIG1ldGhvZCA9ICJsbSIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhwYWxldHRlXzM3KSkgKwogIGdlb21fc21vb3RoKGFlcyh4ID0geWVhcmx5X21lYW5fYnlwb2ludF9TRCwgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiksIG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgY29sb3IgID0gImJsYWNrIikgKwogIHRoZW1lX2NsYXNzaWMoKQoKI2ZhY2V0IGhlbHBmdWwgZm9yIHZpc3VhbGl6YXRpb24KZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzKSArCiAgbGFicyh4ID0gIlNEIG9mIG1lYW4gYm90dG9tIHRlbXBlcmF0dXJlIiwgIHkgPSAiQnJheSBDdXJ0aXMgYmFsYW5jZWQgZGlzc2ltaWxhcml0eSIpICsKICBnZW9tX3BvaW50KGFlcyh4ID0geWVhcmx5X21lYW5fYnlwb2ludF9TRCwgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiwgY29sb3IgPSBzdXJ2ZXlfdW5pdCksIGFscGhhID0gMC4zKSArCiAgZ2VvbV9saW5lKGFlcyh4ID0geWVhcmx5X21lYW5fYnlwb2ludF9TRCwgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiwgY29sb3IgPSBzdXJ2ZXlfdW5pdCksIHN0YXQ9InNtb290aCIsIG1ldGhvZCA9ICJsbSIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhwYWxldHRlXzM3KSkgKwogIGdlb21fc21vb3RoKGFlcyh4ID0geWVhcmx5X21lYW5fYnlwb2ludF9TRCwgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiksIG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgY29sb3IgID0gImJsYWNrIikgKwogIGZhY2V0X3dyYXAofnN1cnZleV91bml0LCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9jbGFzc2ljKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibnVsbCIpCgpgYGAKClRoZSBtZWFuIHRlbXBlcmF0dXJlIHBlcmZvcm1zIGVxdWFsbHkgd2VsbCwgYnV0IGV4cGxhaW5zIGxpdHRsZSB2YXJpYXRpb24uIAoqTm90ZSB0aGF0IHRoaXMgcGxvdCBpcyBqdXN0IHRvIGhlbHAgdmlzdWFsaXplIGRhdGEgYW5kIHBhdHRlcm5zLCAgaXQgZG9lcyBub3QgcGxvdCBwcmVkaWN0ZWQgdmFsdWVzIGZyb20gdGhlIExNRSBidXQgcmF0aGVyIGp1c3Qgc2ltcGxlIGxpbmVhciBtb2RlbHMgb2YgZGlzc2ltaWxhcml0eSB+IHRlbXAuCmBgYHtyIHBsb3QgZGlzc2ltaWxhcml0eSB2cy4gbWVhbiB0ZW1wZXJhdHVyZX0KZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzKSArCiAgbGFicyh4ID0gIk1lYW4gYm90dG9tIHRlbXBlcmF0dXJlICjLmkMpIiwgIHkgPSAiQnJheSBDdXJ0aXMgYmFsYW5jZWQgZGlzc2ltaWxhcml0eSIpICsKICBnZW9tX3BvaW50KGFlcyh4ID0geWVhcmx5X21lYW5fYnlwb2ludF9hdmcsIHkgPSBicmF5X2N1cnRpc19kaXNzaW1pbGFyaXR5X2JhbGFuY2VkX21lYW4sIGNvbG9yID0gc3VydmV5X3VuaXQpLCBhbHBoYSA9IDAuMykgKwogIGdlb21fbGluZShhZXMoeCA9IHllYXJseV9tZWFuX2J5cG9pbnRfYXZnLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgc3RhdD0ic21vb3RoIiwgbWV0aG9kID0gImxtIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKHBhbGV0dGVfMzcpKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2ZywgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiksIG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgY29sb3IgID0gImJsYWNrIikgKwogIHRoZW1lX2NsYXNzaWMoKQoKI2ZhY2V0ZWQgaGVscGZ1bCBmb3IgdmlzdWFsaXphdGlvbgpnZ3Bsb3QoZGF0YSA9IGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMpICsKICBsYWJzKHggPSAiTWVhbiBib3R0b20gdGVtcGVyYXR1cmUgKMuaQykiLCAgeSA9ICJCcmF5IEN1cnRpcyBiYWxhbmNlZCBkaXNzaW1pbGFyaXR5IikgKwogIGdlb21fcG9pbnQoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2ZywgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiwgY29sb3IgPSBzdXJ2ZXlfdW5pdCksIGFscGhhID0gMC4zKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMocGFsZXR0ZV8zNykpICsKICBmYWNldF93cmFwKH5zdXJ2ZXlfdW5pdCwgc2NhbGVzID0gImZyZWUiKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2ZywgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiksIG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgY29sb3IgID0gImJsYWNrIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm51bGwiKQpgYGAKCgojIyNUaGVuLCB3ZSBsb29rZWQgYXQgcmVsYXRpdmUgdGVtcGVyYXR1cmUgcHJlZGljdG9ycyAoc2NhbGVkIHdpdGhpbiBhIHN1cnZleSByZWdpb24sIHNvLCBpcyB0aGlzIHllYXIgd2FybSBvciBjb29sIGZvciB0aGlzIHJlZ2lvbikKLSBSZWxhdGl2ZSBtZWFuIGJvdHRvbSB0ZW1wIDEyIG1vbnRocyBiZWZvcmUgc3VydmV5Ci0gUmVsYXRpdmUgbWF4IGJvdHRvbSB0ZW1wIDEyIHllYXJzIGJlZm9yZSBzdXJ2ZXkKLSBSZWxhdGl2ZSBtaW4gYm90dG9tIHRlbXAgMTIgeWVhcnMgYmVmb3JlIHN1cnZleQotIFJlbGF0aXZlIGJvdHRvbSB0ZW1wIHNlYXNvbmFsaXR5IDEyIG1vbnRocyBiZWZvcmUgc3VydmV5Ci0gUmVsYXRpdmUgaGV0ZXJvZ2VuZWl0eSAoU0QpIG9mIG1lYW4gYm90dG9tIHRlbXAgMTIgbW9udGhzIGJlZm9yZSBzdXJ2ZXkKLSBSZWxhdGl2ZSBoZXRlcm9nZW5laXR5IChTRCkgb2YgbWF4IGJvdHRvbSB0ZW1wIDEyIG1vbnRocyBiZWZvcmUgc3VydmV5Ci0gUmVsYXRpdmUgaGV0ZXJvZ2VuZWl0eSAoU0QpIG9mIG1pbiBib3R0b20gdGVtcCAxMiBtb250aHMgYmVmb3JlIHN1cnZleQotIFJlbGF0aXZlIGhldGVyb2dlbmVpdHkgKFNEKSBvZiBib3R0b20gdGVtcCBzZWFzb25hbHR5IDEyIG1vbnRocyBiZWZvcmUgc3VydmV5CgpgYGB7ciBzY2FsZWQgdGVtcCBtb2RlbCByZXN1bHRzfQoKYmFsYW5jZWRfZGlzc2ltaWxhcml0eV9zYnRfbW9kZWxfcmVzdWx0c1tTY2FsZWQgPT0gVCxdCmBgYApUaGUgcmVsYXRpdmUgbWVhbiB0ZW1wZXJlYXR1cmUgcGVyZm9ybXMgYmVzdCwgYnV0IGV4cGxhaW5zIDAgdmFyaWF0aW9uLiAKKk5vdGUgdGhhdCB0aGlzIHBsb3QgaXMganVzdCB0byBoZWxwIHZpc3VhbGl6ZSBkYXRhIGFuZCBwYXR0ZXJucywgIGl0IGRvZXMgbm90IHBsb3QgcHJlZGljdGVkIHZhbHVlcyBmcm9tIHRoZSBMTUUgYnV0IHJhdGhlciBqdXN0IHNpbXBsZSBsaW5lYXIgbW9kZWxzIG9mIGRpc3NpbWlsYXJpdHkgfiB0ZW1wLgpgYGB7ciBwbG90IGRpc3NpbWlsYXJpdHkgdnMuIHJlbGF0aXZlIG1lYW4gdGVtcGVyYXR1cmV9CmdncGxvdChkYXRhID0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19yZWdzdGF0cykgKwogIGxhYnMoeCA9ICJNZWFuIGJvdHRvbSB0ZW1wZXJhdHVyZSBzY2FsZWQiLCAgeSA9ICJCcmF5IEN1cnRpcyBiYWxhbmNlZCBkaXNzaW1pbGFyaXR5IikgKwogIGdlb21fcG9pbnQoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX2xpbmUoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgc3RhdD0ic21vb3RoIiwgbWV0aG9kID0gImxtIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKHBhbGV0dGVfMzcpKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuKSwgbWV0aG9kID0gImxtIiwgc2UgPSBGLCBjb2xvciAgPSAiYmxhY2siKSArCiAgdGhlbWVfY2xhc3NpYygpCgojZmFjZXRlZCBoZWxwZnVsIGZvciB2aXN1YWxpemF0aW9uCmdncGxvdChkYXRhID0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19yZWdzdGF0cykgKwogIGxhYnMoeCA9ICJNZWFuIGJvdHRvbSB0ZW1wZXJhdHVyZSBzY2FsZWQiLCAgeSA9ICJCcmF5IEN1cnRpcyBiYWxhbmNlZCBkaXNzaW1pbGFyaXR5IikgKwogIGdlb21fcG9pbnQoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX2xpbmUoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgc3RhdD0ic21vb3RoIiwgbWV0aG9kID0gImxtIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKHBhbGV0dGVfMzcpKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuKSwgbWV0aG9kID0gImxtIiwgc2UgPSBGLCBjb2xvciAgPSAiYmxhY2siKSArCiAgZmFjZXRfd3JhcCh+c3VydmV5X3VuaXQsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2NsYXNzaWMoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJudWxsIikKYGBgCgojIyNGaXNoaW5nIFByZXNzdXJlIEFsb25lCmBgYHtyfQojbW9kZWwgcmFua2luZyBmb3IgZmlzaGluZyBvbmx5IG1vZGVscwoKI2Zyb20gbG9jYWwgKHdpbGwgaGF2ZSB0byBjaGFuZ2UpCmJhbGFuY2VkX2Rpc3NpbWlsYXJpdHlfZmlzaGluZ19tb2RlbF9yZXN1bHRzIDwtcmVhZFJEUyhoZXJlOjpoZXJlKCJvdXRwdXQiLCJiYWxhbmNlZF9kaXNzaW1pbGFyaXR5X2Zpc2hpbmdfbW9kZWxfcmVzdWx0cy5SZHMiKSkKCnNldG9yZGVyKGJhbGFuY2VkX2Rpc3NpbWlsYXJpdHlfZmlzaGluZ19tb2RlbF9yZXN1bHRzLCAtQUlDYykKCmJhbGFuY2VkX2Rpc3NpbWlsYXJpdHlfZmlzaGluZ19tb2RlbF9yZXN1bHRzCmBgYApCZXN0IG1vZGVsIG9ubHkgaW5jbHVkZXMgc3VydmV5IHVuaXQgKHByb2JhYmx5IGJlY2F1c2Ugb2YgZGlmZmVyZW5jZXMgaW4gYmFzZWxpbmUgZGlzc2ltaWxhcml0eSBhY3Jvc3MgcmVnaW9ucykKCgojIyNOb3cgd2UnbGwgbG9vayBhdCBib3RoIGZpc2hpbmcgYW5kIGJvdHRvbSB0ZW1wZXJhdHVyZSBhcyBwb3RlbnRpYWwgcHJlZGljdG9ycwoKYGBge3J9CiNtb2RlbCByYW5raW5ncyAodGVtcCBhbmQgZmlzaGluZykKI2Zyb20gbG9jYWwgKHdpbGwgaGF2ZSB0byBjaGFuZ2UpCmJhbGFuY2VkX2Rpc3NpbWlsYXJpdHlfc2J0X2Zpc2hpbmdfbW9kZWxfcmVzdWx0cyA8LSByZWFkUkRTKGhlcmU6OmhlcmUoIm91dHB1dCIsICJiYWxhbmNlZF9kaXNzaW1pbGFyaXR5X3NidF9maXNoaW5nX21vZGVsX3Jlc3VsdHMuUmRzIikpCgpzZXRvcmRlcihiYWxhbmNlZF9kaXNzaW1pbGFyaXR5X3NidF9maXNoaW5nX21vZGVsX3Jlc3VsdHMsIC1BSUNjKQpiYWxhbmNlZF9kaXNzaW1pbGFyaXR5X3NidF9maXNoaW5nX21vZGVsX3Jlc3VsdHMKYGBgCkFueSBtb2RlbCB3aXRoIHN1cnZleSBhcyBhIGZpeGVkIGVmZmVjdCBwZXJmb3JtcyBiZXR0ZXIgdGhhbiBtb2RlbHMgd2l0aG91dCBzdXJ2ZXkgYXMgYSBmaXhlZCBlZmZlY3QuIEFsc28sIHRoZXJlIGlzIGFuIGludGVyYWN0aW9uIGJldHdlZW4gZmlzaGluZyBhbmQgc3VydmV5IGluIDQgb2YgdGhlIHRvcCA1IHBlcmZvcm1pbmcgbW9kZWxzLiAKClNpZ25pZmljYW50IHBvc2l0aXZlIGludGVyYWN0aW9uIChoaWdoZXIgZGlzc2ltaWxhcml0eSBhdCBoaWdoZXIgZmlzaGluZykKLSBOZXdmb3VuZGxhbmQKClNpZ25pZmljYW50IG5lZ2F0aXZlIGludGVyYWN0aW9uIChoaWdoZXIgZGlzc2ltaWxhcml0eSBhdCBsb3dlciBmaXNoaW5nKQotIEVhc3Rlcm4gQmVyaW5nIFNlYQotIEZyYW5jZQotIEd1bGYgb2YgQWxhc2thCi0gR3VsZiBvZiBTdC4gTGF3cmVuY2UgUwotIE5vcnRoZWFzdCBVUyBGYWxsCi0gSXJlbGFuZCA0dGggcXVhcnRlcgotIE5vcnRoIFNlYSAoMXN0IGFuZCAzcmQgcXVhcnRlcikKLSBXZXN0IENvYXN0IGFuZCBFYXN0IENvYXN0IG9mIFNvdXRoIElzbGFuZCBvZiBOZXcgWmVhbGFuZAotIFNvdXRoIEdlb3JnaWEKLSBTY290aWFuIFNoZWxmIFN1bW1lciBTdXJ2ZXkKCgpQbG90IGp1c3QgZGlzc2ltaWxhcml0eSB+IHJlbGF0aXZlIGZpc2hpbmcgcHJlc3N1cmUgY29lZmZpY2llbnRzIG9mIGVhY2ggcmVnaW9uIChMaWtlIGZpZ3VyZSAxYikKKk5vdGUsIG1heSBiZSBiZXR0ZXIgdG8gaW5jbHVkZSBzdXJ2ZXkgYXMgYSBmaXhlZCBlZmZlY3QsIGJ1dCBiZWxvdyB3ZSBpbmNsdWRlIGFzIHJhbmRvbSBzbG9wZSBhbmQgaW50ZXJjZXB0IGluc3RlYWQuIApgYGB7cn0KI2xtZXIgd2l0aCBmaXNoaW5nIGFzIGZpeGVkIGFuZCBzdXJ2ZXkgYXMgcmFuZG9tIHNsb3BlIGFuZCBpbnRlcmNlcHQKI2Zpc2hpbmcgYW5kIHJhbmRvbSBzbG9wZSBhbmQgaW50ZXJjZXB0IGZvciBzdXJ2ZXkKYWxscmVnX2Rpc3NpbWlsYXJpdHlfZmlzaGluZ19tZWFuX21vZCA8LSBsbWVyKGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbiB+IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnICsgKDEgKyBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZ3xzdXJ2ZXlfdW5pdCksIGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzKQogICAgICAgICAgICAgICAgIAoKICMgc2VlIGdyb3VwIGNvZWZmaWNpZW50cyBhbmQgY29uZmlkZW5jZSBpbnRlcnZhbHMKZmlzaGluZ19tb2RlbF9jb2Vmc19yZWR1Y2VkIDwtIGRhdGEudGFibGUodHJhbnNmb3JtKGFzLmRhdGEuZnJhbWUocmFuZWYoYWxscmVnX2Rpc3NpbWlsYXJpdHlfZmlzaGluZ19tZWFuX21vZCkpLCBsd3IgPSBjb25kdmFsIC0gMS45Nipjb25kc2QsIHVwciA9IGNvbmR2YWwgKyAxLjk2KmNvbmRzZCkpCiNodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82OTgwNTUzMi9leHRyYWN0LXRoZS1jb25maWRlbmNlLWludGVydmFscy1vZi1sbWVyLXJhbmRvbS1lZmZlY3RzLXBsb3R0ZWQtd2l0aC1kb3RwbG90cmEKCgojT05MWSBTTE9QRVMKZmlzaGluZ19tb2RlbF9jb2Vmc19yZWR1Y2VkIDwtIGZpc2hpbmdfbW9kZWxfY29lZnNfcmVkdWNlZFt0ZXJtID09ICJzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyIsXQoKZmlzaGluZ19tb2RlbF9jb2Vmc19yZWR1Y2VkWyxzdXJ2ZXlfdW5pdCA6PSBncnBdWyxzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyA6PSBjb25kdmFsXQoKCmZpc2hpbmdfbW9kZWxfY29lZnNfcmVkdWNlZFssU2xvcGVfRGlyZWN0aW9uIDo9IGlmZWxzZShzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyA+IDAsICJQb3NpdGl2ZSIsIk5lZ2F0aXZlIildCgojCmZpc2hpbmdfbW9kZWxfY29lZnNfcmVkdWNlZCA8LSBmaXNoaW5nX21vZGVsX2NvZWZzX3JlZHVjZWRbY29sb3JfbGluaywgb24gPSAic3VydmV5X3VuaXQiXQoKCiNkb2VzIGl0IGNyb3NzIHplcm8/CmZpc2hpbmdfbW9kZWxfY29lZnNfcmVkdWNlZFssc2lnbmlmaWNhbnQgOj0gaWZlbHNlKGx3ciA+MCAmIHVwcj4wLFQsaWZlbHNlKGx3cjwwICYgdXByPDAsVCxGKSldCgojZGVsZXRlIGFsbCBvYnMgdGhhdCBhcmUgc2lnbmlmaWNhbnQKZmlzaGluZ19tb2RlbF9jb2Vmc19yZWR1Y2VkLnIgPC0gZmlzaGluZ19tb2RlbF9jb2Vmc19yZWR1Y2VkW3NpZ25pZmljYW50ID09IEYsXQoKI29yZGVyIHRhYmxlIGJ5IGNvZWZmaWNpZW50CnNldG9yZGVyKGZpc2hpbmdfbW9kZWxfY29lZnNfcmVkdWNlZCwgc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcpCgpCQ19iYWxhbmNlZF9maXNoaW5nX21vZGVsX2NvZWZzX3JlZHVjZWQudW5pcXVlIDwtIHVuaXF1ZShmaXNoaW5nX21vZGVsX2NvZWZzX3JlZHVjZWRbLC4oY29uZHZhbCxjb25kc2QsIGx3ciwgdXByLCBzdXJ2ZXlfdW5pdCwgc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcsIFNsb3BlX0RpcmVjdGlvbiwgaGV4LCBTdXJ2ZXlfTmFtZV9TZWFzb24sIHNpZ25pZmljYW50KV0pIAoKI2V4dHJhY3QgY29sb3IgaGV4ZXMKI3llYXIgYWRqIGNvZWYgb3JkZXIKY29sb3JfeWVhcl9hZGpfb3JkZXIgPC1CQ19iYWxhbmNlZF9maXNoaW5nX21vZGVsX2NvZWZzX3JlZHVjZWQudW5pcXVlWyxoZXhdCgojYWxwaGFiZXRpY2FsIG9yZGVyCkJDX2JhbGFuY2VkX2Zpc2hpbmdfbW9kZWxfY29lZnNfcmVkdWNlZC51bmlxdWUuYWxwaGEgPC0gc2V0b3JkZXIoQkNfYmFsYW5jZWRfZmlzaGluZ19tb2RlbF9jb2Vmc19yZWR1Y2VkLnVuaXF1ZSwgU3VydmV5X05hbWVfU2Vhc29uKQpjb2xvcl9hbHBoYV9vcmRlciA8LSBCQ19iYWxhbmNlZF9maXNoaW5nX21vZGVsX2NvZWZzX3JlZHVjZWQudW5pcXVlLmFscGhhWyxoZXhdCgpnZ3Bsb3QoKSArCiAgICBnZW9tX2Vycm9yYmFyKGRhdGEgPSBmaXNoaW5nX21vZGVsX2NvZWZzX3JlZHVjZWQsIGFlcyh4ID0gcmVvcmRlcihTdXJ2ZXlfTmFtZV9TZWFzb24sIHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnKSAsIHkgPSBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywgbGFiZWwgPSBTdXJ2ZXlfTmFtZV9TZWFzb24sIHltaW4gPSBsd3IsIHltYXggPSB1cHIpLCBmaWxsID0gImdyZXkiLCB3aWR0aCA9IDApICsgI2FkZCBjb25maWRlbmNlIGludGVydmFscwogIGdlb21fcG9pbnQoZGF0YSA9IGZpc2hpbmdfbW9kZWxfY29lZnNfcmVkdWNlZCwgYWVzKHggPSByZW9yZGVyKFN1cnZleV9OYW1lX1NlYXNvbiwgc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcpICwgeSA9IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLCBsYWJlbCA9IFN1cnZleV9OYW1lX1NlYXNvbiwgCiAgICAgIGZpbGwgPSBTbG9wZV9EaXJlY3Rpb24pLCBzdGF0ID0gJ2lkZW50aXR5Jywgc2hhcGUgPSAyMSwgY29sb3IgPSAiYmxhY2siKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygid2hpdGUiLCJibGFjayIpLCBuYW1lID0gIlNsb3BlIERpcmVjdGlvbiIpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXNoaW5nX21vZGVsX2NvZWZzX3JlZHVjZWQuciwgYWVzKHggPSByZW9yZGVyKFN1cnZleV9OYW1lX1NlYXNvbiwgc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcpICwgeSA9IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLCAKICAgICAgICAgIGxhYmVsID0gU3VydmV5X05hbWVfU2Vhc29uKSwgc3RhdCA9ICdpZGVudGl0eScsIGZpbGwgPSAiZ3JleSIsY29sb3IgPSAiZ3JleSIsIHNoYXBlID0gMjEpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArCiAgeGxhYigiU3VydmV5IHVuaXQiKSArCiAgeWxhYigiQmFsYW5jZWQgQkMgZGlzc2ltaWxhcml0eSB+XG5yZWxhdGl2ZSBmaXNoaW5nIHByZXNzdXJlIikgKwogIGNvb3JkX2ZsaXAoKSArCiAgdGhlbWVfY2xhc3NpYygpCgojc2NhdHRlcnBsb3QKZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19yZWdzdGF0cy5uYSA8LSBuYS5vbWl0KGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMsIGNvbHMgPSAic3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWciKSAjZGVsZXRlIGFueSByb3dzIHdpdGggTkFzCgojUHJlZGljdGVkIHZhbHVlcwpkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzLm5hJHByZWRfc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcgPC0gcHJlZGljdChhbGxyZWdfZGlzc2ltaWxhcml0eV9maXNoaW5nX21lYW5fbW9kLHJlLmZvcm09TkEpICAjIyBwb3B1bGF0aW9uIGxldmVsCmRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMubmEkcHJlZF9zdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZ19pbmRpdmlkdWFsIDwtIHByZWRpY3QoYWxscmVnX2Rpc3NpbWlsYXJpdHlfZmlzaGluZ19tZWFuX21vZCkgIyMgaW5kaXZpZHVhbCBsZXZlbAoKI2NvbmZpZGVuY2UgaW50ZXJ2YWxzCmZpc2hpbmdfY29uZml0IDwtIGNvbmZpbnQoYWxscmVnX2Rpc3NpbWlsYXJpdHlfZmlzaGluZ19tZWFuX21vZCwgb2xkTmFtZXMgPSBGKQoKI3VwcGVyIGxvd2VyIGJvdW5kcyBmcm9tIGNvbmZpZGVuY2UgaW50ZXJ2YWxzCmRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMubmFbLHByZWRfc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWdfbHdyIDo9IGZpc2hpbmdfY29uZml0WzUsMV0gKyBmaXNoaW5nX2NvbmZpdFs2LDFdKnN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnXSNsb3dlciBjb25maWRlbmNlIGludGVydmFsCmRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMubmFbLHByZWRfc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWdfdXByIDo9IGZpc2hpbmdfY29uZml0WzUsMl0gKyBmaXNoaW5nX2NvbmZpdFs2LDJdKnN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnXSN1cHBlciBjb25maWRlbmNlIGludGVydmFsCgoKI2ZvciBhbGwgcmVnaW9ucwpnZ3Bsb3QoZGF0YSA9IGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMubmEpICsKICBsYWJzKHggPSAiUmVsYXRpdmUgZmlzaGluZyBwcmVzc3VyZSIsICB5ID0gIkJDIGJhbGFuY2VkIGRpc3NpbWlsYXJpdHkiKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX2xpbmUoYWVzKHggPSBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywgeSA9IHByZWRfc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWdfaW5kaXZpZHVhbCwgY29sb3IgPSBzdXJ2ZXlfdW5pdCkpICsKICBnZW9tX2xpbmUoYWVzKHggPSBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywgeSA9IHByZWRfc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcpLCBsd2QgPSAxKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9ICBwYWxldHRlXzM3KSArCiAgdGhlbWVfY2xhc3NpYygpCgoKCiNmb3IgYWxsIHJlZ2lvbnMgZmFjZXRlZApnZ3Bsb3QoZGF0YSA9IGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMubmEpICsKICBsYWJzKHggPSAiUmVsYXRpdmUgZmlzaGluZyBwcmVzc3VyZSIsICB5ID0gIkJDIGJhbGFuY2VkIGRpc3NpbWlsYXJpdHkiKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX2xpbmUoYWVzKHggPSBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywgeSA9IHByZWRfc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWdfaW5kaXZpZHVhbCwgY29sb3IgPSBzdXJ2ZXlfdW5pdCkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gIHBhbGV0dGVfMzcpICsKICBmYWNldF93cmFwKH5zdXJ2ZXlfdW5pdCwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJudWxsIikKCgoKYGBgCgpPdGhlciB2YXJpYWJsZXMgdG8gY29uc2lkZXIKCi0gU3BlY2llcyBudW1iZXIgKHNwcF9jb3VudF9hbm51YWwsIGRpZmZlcmVudCB2YWx1ZSBlYWNoIHJlZ2lvbiBhbmQgeWVhcikKClNwZWNpZXMgbnVtYmVyIGluIGEgeWVhciB2cy4gZGlzc2ltaWxhcml0eQpgYGB7cn0KZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzKSArCiAgbGFicyh4ID0gIlNwcCBudW1iZXIiLCAgeSA9ICJCQyBiYWxhbmNlZCBkaXNzaW1pbGFyaXR5IikgKwogIGdlb21fcG9pbnQoYWVzKHggPSBzcHBfY291bnRfYW5udWFsLCB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuLCBjb2xvciA9IHN1cnZleV91bml0KSwgYWxwaGEgPSAwLjMpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gIHBhbGV0dGVfMzcpICsKICMgZmFjZXRfd3JhcCh+c3VydmV5X3VuaXQsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibnVsbCIpCmBgYApTcGVjaWVzIG51bWJlciBpbiBhIHllYXIgdnMuIGRpc3NpbWlsYXJpdHkgfiB5ZWFyIGNvZWZmaWNpZW50CmBgYHtyfQpkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX3JlZ3N0YXRzLnVuaXF1ZSA8LSB1bmlxdWUoZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19yZWdzdGF0c1ssLih5ZWFyLCBzcHBfY291bnRfYW5udWFsLCBicmF5X2NvZWYsIHN1cnZleV91bml0KV0pCgpnZ3Bsb3QoZGF0YSA9IGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfcmVnc3RhdHMudW5pcXVlKSArCiAgbGFicyh4ID0gIlNwcCBudW1iZXIiLCAgeSA9ICJCcmF5IEN1cnRpcyBkaXNzaW1pbGFyaXR5IH4geWVhciBjb2VmZmljaWVudCIpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gc3BwX2NvdW50X2FubnVhbCwgeSA9IGJyYXlfY29lZiwgY29sb3IgPSBzdXJ2ZXlfdW5pdCksIGFscGhhID0gMC4zKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9ICBwYWxldHRlXzM3KSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKwogIHRoZW1lX2NsYXNzaWMoKQpgYGAKUmVnaW9ucyB0aGF0IGFyZSBkaWZmZXJlbnRpYXRpbmcgKHBvc2l0aXZlIHNsb3BlKSB0ZW5kIHRvIGhhdmUgZmV3ZXIgI3Mgb2Ygc3BlY2llcy4gVGhlIGZldyByZWdpb25zIHdpdGggYSBsb3Qgb2Ygc3BlY2llcyAob3ZlciAxNTA7IEd1bGYgb2YgTWV4aWNvLCBXZXN0IENvYXN0IFVTLCBOb3J0aGVhc3QgVVMsIEd1bGYgb2YgQWxhc2thKSwgYWxsIGhhdmUgbmVnYXRpdmUgY29lZmZpY2llbnRzIChob21vZ2VuaXppbmcpLiBUaGlzIGlzIHRoZSBvcHBvc2l0ZSBvZiB3aGF0IEkgd291bGQgaGF2ZSBleHBlY3RlZCwgYXMgbW9yZSBzcGVjaWVzIGFjcm9zcyBhIHN1cnZleSByZWdpb24gd291bGQgaW50dWl0aXZlbHkgYWxsb3cgZm9yIG1vcmUgb3Bwb3J0dW5pdGllcyB0byBkaWZmZXJlbnRpYXRlLiAK